#pragma once
#include <iostream>
#include <string>
#include<jsoncpp/json/json.h>

const std::string blankspace_sep = " "; // 空格分隔符
const std::string protocol_sep = "\n";  // 协议分隔符

//      "x op y"     ==>    "len""\n""x op y""\n"
std::string Encode(const std::string &content)
{
    std::string package = std::to_string(content.size());
    package += protocol_sep;
    package += content;
    package += protocol_sep;

    return package;
}

//    "len""\n""x op y""\n"     ==>    "x op y"
bool Decode(std::string &package, std::string *content)
{
    auto left_protocol_sep = package.find(protocol_sep);
    if (left_protocol_sep == std::string::npos)
        return false;

    // 长度字符串
    std::string len_str = package.substr(0, left_protocol_sep);
    // 长度字符串表示长度
    int len = std::stoi(len_str);

    int total_lens = len + 2 + len_str.size();

    //报文不完整
    if (package.size() < total_lens)
        return false;

    *content = package.substr(left_protocol_sep + 1, len);

    // 移除报文
    package.erase(0, total_lens);
    return true;
}

class Request
{
public:
    Request(int data1, int data2, char oper) : x(data1), y(data2), op(oper)
    {
    }

    Request()
    {
    }

    ~Request()
    {
    }

    //"x op y"
    bool Serialize(std::string *out)
    {
#ifdef Myself
        std::string s = std::to_string(x);
        s += blankspace_sep;
        s += op;
        s += blankspace_sep;
        s += std::to_string(y);

        *out = s;
        return true;
#else
        Json::Value root;
        root["x"]=x;
        root["y"]=y;
        root["op"]=op;

        Json::StyledWriter w;
        *out=w.write(root);
        return true;
#endif
    }

    bool Deserialize(const std::string &in) //"x op y"
    {
#ifdef Myself
        // 找x
        auto left = in.find(blankspace_sep);
        if (left == std::string::npos)
        {
            return false;
        }
        std::string part_left = in.substr(0, left);

        // 找y
        auto right = in.rfind(blankspace_sep);
        if (right == std::string::npos)
        {
            return false;
        }
        std::string part_right = in.substr(right + 1);

        if (left + 2 != right)
        {
            return false;
        }

        x = std::stoi(part_left);
        op = in[left + 1];
        y = std::stoi(part_right);

        return true;
#else
        Json::Value root;
        Json::Reader r;
        r.parse(in,root);
        x=root["x"].asInt();
        y=root["y"].asInt();
        op=root["op"].asInt();

        return true;
#endif
    }

public:
    int x;
    int y;
    char op; // 操作符
};

class Response
{
public:
    Response(int res, int code) : result(res), errcode(code)
    {
    }

    ~Response()
    {
    }

    //"result errcode"
    bool Serialize(std::string *out)
    {
#ifdef Myself
        std::string s = std::to_string(result);
        s += blankspace_sep;
        s += std::to_string(errcode);

        *out = s;
        return true;
#else
        Json::Value root;
        root["result"]=result;
        root["errcode"]=errcode;
        Json::StyledWriter w;
        *out=w.write(root);

        return true;
#endif
    }

    bool Deserialize(const std::string &in) //"result errcode"
    {
#ifdef Myself
        auto pos = in.find(blankspace_sep);
        if (pos == std::string::npos)
        {
            return false;
        }
        std::string part_left = in.substr(0, pos);
        std::string part_right = in.substr(pos + 1);

        result = std::stoi(part_left);
        errcode = std::stoi(part_right);

        
        return true;
#else 
        Json::Reader r;
        Json::Value root;
        r.parse(in,root);
        result=root["result"].asInt();
        errcode=root["errcode"].asInt();
#endif
    }

public:
    int result;  // 结果
    int errcode; // 为0则结果正确 !0,对应的数字代表错误原因
};